#if 0
#include "circle_buffer.h"

#include <ctype.h>
#include <memory.h>
#include <stdlib.h>

#include "log.h"

// 只是为了显示更清楚
#define clear_after_read

/**
	@brief 创建环形缓冲区
	@param uint32_t capacity初始容量
	@return 创建成功，返回指针；创建失败，返回NULL
*/
circle_buffer *circle_buffer_create(uint32_t capacity) {
	// 变量与类型不能重名，不是类型名时，可以定义为相同
	// VSCode 还是 gcc
	circle_buffer *buffer = (circle_buffer *)calloc(1, sizeof(circle_buffer));
	if (!buffer) {
		log_error("环形缓冲区创建失败\n");
		return NULL;
	}
	buffer->data = (byte *)calloc(capacity, sizeof(byte));
	if (!buffer->data) {
		log_error("环形缓冲区空间申请失败\n");
		free(buffer);
		return NULL;
	}
	buffer->capacity = capacity;
	buffer->begin = 0;
	buffer->end = 0;
	buffer->mutex = ({
		pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
		mutex;
	});
	return buffer;
}
/**
	@brief 销毁环形缓冲区
	@param circle_buffer* circle_buffer要销毁的环形缓冲区
	@return 销毁成功，返回NULL；销毁失败，返回传入指针
*/
circle_buffer *circle_buffer_destory(circle_buffer *circle_buffer) {
	if (!circle_buffer) {
		return NULL;
	}
	if (pthread_mutex_trylock(&circle_buffer->mutex)) {
		log_error("获取锁失败\n");
		return circle_buffer;
	}
	if (circle_buffer) {
		free(circle_buffer->data);
	}
	pthread_mutex_unlock(&circle_buffer->mutex);
	pthread_mutex_destroy(&circle_buffer->mutex);
	free(circle_buffer);
	return NULL;
}
/**
	@brief 从环形缓冲区读取数据，配合获取剩余数据大小
	@param circle_buffer* circle_buffer要读取的环形缓冲区
	@param byte[] destination读取到的数据存放位置
	@param uint32_t max_size最多读取字节数
	@return 实际读取到的字节数
*/
int32_t circle_buffer_read(circle_buffer *circle_buffer, byte destination[],
						   uint32_t max_size) {
	if (											 //
		!circle_buffer ||							 // 缓冲区为NULL
		!destination ||								 // 目标为NULL
		!max_size ||								 // 最大读取长度为0
		(circle_buffer->begin == circle_buffer->end) // 缓冲区为空
	) {
		// 未能读取到数据
		return 0;
	}
	// 尝试加锁
	if (pthread_mutex_trylock(&circle_buffer->mutex)) {
#define try_lock_fail (-1)
		// 尝试加锁失败
		return try_lock_fail;
	}
	/*
		1.顺序
				<------copy-----> [ < max_size ]
				<begin>			<end>
			[---------------------------]
			<0>							<capacity>
		2.逆序
							<----copy---> [ < max_size ]
				<end>		<begin>
			[---------------------------]
			<0>							<capacity>
	*/
	// ! 一共两次复制
	// !第一次复制必选（不考虑首尾相接）
	// ! 第二次复制可选（一定是从buffer的开头复制）
	// 第一次复制从<begin>开始，如果分段，结束在容量；如果不分段，结束在数据结束
	// 缓冲区为空已处理，只有顺序或逆序的情况
	// <begin> ~ <结束> 数据长度
	uint32_t copy = ((circle_buffer->begin < circle_buffer->end)
						 ? circle_buffer->end
						 : circle_buffer->capacity) // 结束位置
					- circle_buffer->begin;			// 起始位置
	// 实际复制的数据长度 <最大读取长度> 和 <数据长度> 中较小的
	if (max_size < copy) {
		copy = max_size;
	}
	// 第一次复制总是向destination[0]复制
	memcpy(destination + 0, circle_buffer->data + circle_buffer->begin, copy);
#ifdef clear_after_read
	memset(circle_buffer->data + circle_buffer->begin, 0, copy);
#endif
	// 只有逆序且长度不够，才再次复制
	// 所以顺序或长度足够，返回
	// 缓冲区为空，已处理
	if (											   //
		(circle_buffer->begin < circle_buffer->end) || // 顺序
		(copy == max_size)							   // 长度足够
	) {
		circle_buffer->begin += copy;
		// 实际应该只有一种情况：读取全部数据，起始位置设置为0
		// circle_buffer->begin %= circle_buffer->capacity;
		if (circle_buffer->begin == circle_buffer->capacity) {
			circle_buffer->begin = 0;
		}
		// 解锁
		pthread_mutex_unlock(&circle_buffer->mutex);
		// 返回一次复制的长度
		return copy;
	}
	// ----------------------------------------------------------------------------
	// ! 到这里一定是首尾相接，且尾部数据不够
	/*
			<--->copy2 [ < max_size' ]
				<end>	<begin>
			[-------------------]
			<0>					<capacity>
	*/
	// 最大可读取长度减少已经复制的长度
	max_size -= copy;
	// 第二段总是从buffer[0]开始，数据长度
	// copy保留，用作 目标数组的偏移量 和 计算读取长度
	uint32_t copy2 = circle_buffer->end - 0;
	// 实际复制长度 <数据长度>  和 <最大读取长度（考虑已经读取的部分）> 中较小的
	if (max_size < copy2) {
		copy2 = max_size;
	}
	// 复制第二部分（考虑已经读取的部分）
	memcpy(destination + copy, circle_buffer->data + 0, copy2);
#ifdef clear_after_read
	memset(circle_buffer->data + 0, 0, copy2);
#endif
	// 不可能又分段，又超出长度，不调整
	circle_buffer->begin = copy2;
	// 解锁
	pthread_mutex_unlock(&circle_buffer->mutex);
	// 返回两次复制长度
	return copy + copy2;
}
/**
	@brief 向环形缓冲区写数据
	@param circle_buffer*circle_buffer 要写入的环形缓冲区
	@param const_uint8_t[] source 要写入的源数据
	@param uint32_t size 源数据字节数
	@return 实际写入的字节数。写入成功，返回size；写入失败，返回0
*/
int32_t circle_buffer_write(circle_buffer *circle_buffer,
							const uint8_t source[], uint32_t size) {
	/*
		空闲容量计算
		1.begin ~ end
			capacity - (end - begin)
			= capacity + (begin - end)
			= (capacity + begin) - end
		2.end ~ begin
			begin - end
		都要再-1，作为 空 和 满 区别
		要求 capacity + begin 不溢出；或者先相减，使用负数
		剩余容量计算包含容量计算（为空）

		1.顺序
			<---idle2--->							<---idle1--->
						<begin>						<end>
			[---------------------------------------------------]
			<0>													<capacity>
		2.逆序
						<----------idle--------->
						<end>					<begin>
			[---------------------------------------------------]
			<0>													<capacity>
		=======================================================================
		加capacity将end推到下一个周期
							<---idle*--->
		<--->idle2	   idle1<-------><-->idle2	   idle1<------->
			<begin>			<end>		<begin>			<end>
		[---------------------------][--------------------------]
		<0>							<capacity>
									<0>							<capacity>
	*/
	if (									 //
		!circle_buffer ||					 // 缓冲区为NULL
		!source ||							 // 数据源为NULL
		!size ||							 // 数据源长度为0
		(circle_buffer->capacity <= size) || // 全部容量不够
											 // 至少一个空闲，相等也是不够存放的
		(									 //
			((circle_buffer->capacity +		 // 容量
			  circle_buffer->begin -		 // 起始位置
			  circle_buffer->end - 1) %		 // 结束位置
			 circle_buffer->capacity)		 //	这里要先-1
			// 不能使用相等判断，否则当begin==end时，结果为0，也是空间不够
			// 实际应该是缓冲区空，空闲最大
			// 因为短路运算，所以到这里通过了之前的全部容量检测，所以可以存的下
			< size) // 剩余容量不够
	) {
		// 实际写入长度为0
		return 0;
	}
	if (pthread_mutex_trylock(&circle_buffer->mutex)) {
		log_error("尝试加锁失败\n");
		return try_lock_fail;
	}
	/*
		1.顺序
											<----copy---> [ < size' ]
											<end>
					<begin>					<end>
			[-------------------------------------------]
			<0>											<capacity>
		2.逆序
														<> copy=0 [ < size' ]
														<end>
					<end>					<begin>
			[-------------------------------------------]
			<0>											<capacity>
	*/
	// ! 一共两次复制
	// ! 第一次复制必选，可能存在复制长度为0
	// ! 第二次复制可选
	// 从<begin>开始的数据结束位置，顺序为<end>；逆序为<capacity>
	// 可能相等，当缓冲区为空时。选择<end>为写入位置
	uint32_t end = (circle_buffer->begin <= circle_buffer->end)
					   ? circle_buffer->end
					   : circle_buffer->capacity;
	// 空闲长度，不考虑首尾相接时，最大写入长度
	uint32_t copy = circle_buffer->capacity - end;
	// 实际复制长度，<空闲长度> 和 <最大写入长度> 中较小的
	if (size <= copy) {
		copy = size;
	}
	// 复制，第一次复制从source[0]开始
	memcpy(circle_buffer->data + end, source + 0, copy);
	// 空间不够已处理，不考虑
	// 如果实际复制长度为写入长度，写入结束，返回；否则，继续复制
	if (copy == size) {
		circle_buffer->end += copy;
		// circle_buffer->end %= circle_buffer->capacity;
		// 调整
		if (circle_buffer->end == circle_buffer->capacity) {
			circle_buffer->end = 0;
		}
		// 解锁
		pthread_mutex_unlock(&circle_buffer->mutex);
		// 返回第一次写入长度
		return copy;
	}
	// =====================================================================
	/*
		1.copy != 0
			<-------> [ < size' ]
			<end2>
					<start>				<end>
			[-------------------------------------------------------]
			<0>														<capacity>
		2.copy == 0
					<---------------> [ < size' ]
					<end2>
					<end>			<start>
			[-------------------------------------------------------]
			<0>														<capacity>
	*/
	// 还未复制长度
	// ! 可能copy为0
	size -= copy;
	// 起始部分的数据结束位置
	// 如果copy不为0，在结尾一定有复制，所以buffer起始没有数据，从0开始
	// 如果copy为0，在结尾未复制，考虑首尾相连
	uint32_t end2 = copy ? 0 : circle_buffer->end;
	// 与读不同，总是有足够空间
	// copy记录数据源已复制的偏移量
	memcpy(circle_buffer->data + end2, source + copy, size);
	// <buffer.end>可能在结尾，可能在开头，可能在中间一段
	// 从<end2>开始，复制size长度
	// 所以<buffer.end>设置参考 新起始（end2）和 复制长度（size'）
	circle_buffer->end = end2 + size;
	// 写入一定有足够空间，不调整
	// 解锁
	pthread_mutex_unlock(&circle_buffer->mutex);
	// 返回两次复制长度之和
	return copy + size;
}
/**
 * @brief 获取剩余数据长度
 * @param const_circle_buffer* circle_buffer 要获取剩余数据长度的环形缓冲区
 * @return 环形缓冲区的剩余数据长度
 */
uint32_t circle_buffer_remain_data_size(const circle_buffer *circle_buffer) {
	/*
		begin ~ end
			end - begin
		end ~ begin
			capacity - (begin - end)
			=capacity + end - begin

		-1
	*/
	return (							 //
			   circle_buffer->capacity + // 容量
			   circle_buffer->end -		 // 结束位置
			   circle_buffer->begin) %	 //	起始位置，不-1,
		   circle_buffer->capacity;		 // 取余，使顺序和逆序使用相同处理程序
}
/**
 * @brief 获取剩余空闲长度
 * @param cons_circle_buffer* circle_buffer 要获取剩余空闲长度的环形缓冲区
 * @return 环形缓冲区的剩余空闲长度
 */
uint32_t circle_buffer_remain_idle_space(const circle_buffer *circle_buffer) {
	/*
		begin ~ end
			capacity - (end - begin)
			=capacity + begin - end
		end ~ begin
			begin - end

		-1
	*/
	return (							 //
			   circle_buffer->capacity + // 容量
			   circle_buffer->begin -	 // 起始位置
			   circle_buffer->end - 1	 // 结束位置
			   ) %						 // -1保留一个空闲位置，分辨空和满
		   circle_buffer->capacity;		 // 取余，使顺序和逆序使用相同处理程序
}
/**
 * @brief 输出环形缓冲区的信息
 * @param const_circle_buffer* circle_buffer 要输出的环形缓冲区
 */
void circle_buffer_display(const circle_buffer *circle_buffer) {
	printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	printf("缓冲区地址：%p\n", circle_buffer);
	if (!circle_buffer) {
		goto end;
	}
	printf("\t数据地址：%p\n", circle_buffer->data);
	if (circle_buffer->data) {
		// 标题
#define _8_bytes_in_line (2)
		/*
			每个字节输出数据2位，空格1位
			8个字节后有2个空格和1个横线
		*/
		printf("\t\t%s\t%-*s\t%s\n", "index", (3 * 8 + 3) * _8_bytes_in_line,
			   "hexdecimal", "ascii");
		// 指向数据
		const byte *data = circle_buffer->data;
		// 实际长度
		uint32_t capacity = circle_buffer->capacity;
		// 8字节一组，长度组数
		uint32_t _capacity = circle_buffer->capacity / (8 * _8_bytes_in_line);
		// 不是整倍数，+1
		_capacity += !!(circle_buffer->capacity % (8 * _8_bytes_in_line));
		// 规整长度
		_capacity *= 8 * _8_bytes_in_line;
		// ascii显示，保留一个'\0'
		char ascii[8 * _8_bytes_in_line + 1] = {0};
		for (uint32_t i = 0, j = 0; i < _capacity; ++i, ++j) {
			// 行首，制表
			if (!(i % (8 * _8_bytes_in_line))) {
				printf("\t\t0x%04x\t", i);
			}
			// 数据
			// 有数据
			if (i < capacity) {
				printf("%02x ", data[i]);
				ascii[j] = isprint(data[i]) ? data[i] : '.';
			}
			// 无数据
			else {
				printf("   ");
				ascii[j] = ' ';
			}

			// ascii
			// 行尾，换行
			if ((i % (8 * _8_bytes_in_line) == (8 * _8_bytes_in_line - 1))) {
				printf("\t%s\n", ascii);
				j = 0 - 1;
			} else if (i % 8 == 7) {
				printf("- ");
			}
		}
	}
	printf("\t容量：%u\n", circle_buffer->capacity);
	printf("\t起始：%u\n", circle_buffer->begin);
	printf("\t结束：%u\n", circle_buffer->end);
	printf("\t数据：%u\n", circle_buffer_remain_data_size(circle_buffer));
	printf("\t空闲：%u\n", circle_buffer_remain_idle_space(circle_buffer));
end:
	printf("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
#endif